package xyz.liut.ee.ws

import jakarta.websocket.*
import jakarta.websocket.server.ServerEndpoint
import xyz.liut.logcat.kt.logDebug
import xyz.liut.logcat.kt.logInfo
import java.io.IOException
import java.nio.ByteBuffer
import java.util.*
import kotlin.concurrent.thread

@Suppress("unused")
@ServerEndpoint(value = "/ws/msg", subprotocols = ["liut"])
class EchoMessage {

    @Volatile
    private var running: Boolean = false

    @OnOpen
    fun onWebSocketConnect(sess: Session) {
        logInfo { "Socket Connected queryString: ${sess}" }

        running = true
        thread {
            while (true) {
                Thread.sleep(2000)
                if (running) {
                    var remoteIp = sess.userProperties["javax.websocket.endpoint.remoteAddress"].toString()
                    remoteIp = remoteIp.substring(1, remoteIp.length)
                    val msg = "heartbeat-${Date()} ... $remoteIp"
                    logDebug { msg }
                    sess.basicRemote.sendText(msg)
                } else {
                    logInfo { "心跳停止" }
                    break
                }
            }
        }
    }

    @OnMessage
    @Throws(IOException::class)
    fun onWebSocketText(sess: Session, message: String) {
        if ("PING" == message) {
            sess.basicRemote.sendText("PONG")
            logDebug { "Received TEXT message: PONG" }
        } else {
            sess.basicRemote.sendText("收到: $message")
            logDebug { "Received TEXT message: $message" }
        }
    }

    @OnMessage
    @Throws(IOException::class)
    fun onWebSocketByteArray(sess: Session, message: ByteArray) {
        logDebug { "Received BYTEARRAY message: $message" }
        sess.basicRemote.sendBinary(ByteBuffer.wrap(message))
    }

    @OnClose
    fun onWebSocketClose(reason: CloseReason) {
        logInfo { "Socket Closed: $reason" }
        running = false
    }

    @OnError
    fun onWebSocketError(cause: Throwable) {
        cause.printStackTrace(System.err)
        running = false
    }

    @Throws(InterruptedException::class)
    fun awaitClosure() {
        logDebug { "Awaiting closure from remote" }
    }


}
